"""
对话式任务管理器
"""
import logging
import json
import re
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
from enum import Enum

from backend.services.ai_service import get_ai_service
from backend.models.core import Task, ValidationResult
from shared.enums import TaskType, AICapability, TaskStatus

logger = logging.getLogger(__name__)


class TaskCommandType(str, Enum):
    """任务命令类型"""
    ADD = "add"
    MODIFY = "modify"
    DELETE = "delete"
    REORDER = "reorder"
    CONFIRM = "confirm"
    UNKNOWN = "unknown"


@dataclass
class TaskCommand:
    """任务命令"""
    type: TaskCommandType
    target_task_index: Optional[int] = None
    target_task_id: Optional[str] = None
    new_description: Optional[str] = None
    new_position: Optional[int] = None
    parameters: Dict[str, Any] = None
    raw_message: str = ""

    def __post_init__(self):
        if self.parameters is None:
            self.parameters = {}


@dataclass
class TaskCommandResult:
    """任务命令执行结果"""
    success: bool
    message: str
    updated_tasks: Optional[List[Task]] = None
    error: Optional[str] = None


class TaskManager:
    """对话式任务管理器"""
    
    def __init__(self):
        self.command_parsing_prompt = """
分析用户对任务列表的修改请求，并返回结构化的命令信息。

当前任务列表：
{task_list}

用户消息：{user_message}

请识别用户想要执行的操作类型：
- add: 添加新任务
- modify: 修改现有任务
- delete: 删除任务
- reorder: 重新排序任务
- confirm: 确认执行任务
- unknown: 无法识别的命令

请返回JSON格式的命令信息：
{{
    "type": "命令类型",
    "target_task_index": 目标任务索引（从1开始，如果适用）,
    "new_description": "新的任务描述（如果是修改或添加）",
    "new_position": 新位置索引（如果是重排序）,
    "parameters": {{
        "任何其他相关参数": "值"
    }},
    "explanation": "操作说明"
}}

注意：
- 任务索引从1开始计数
- 如果用户说"第一个任务"、"第2个任务"等，请正确识别索引
- 如果用户没有明确指定任务，尝试根据描述匹配

只返回JSON，不要其他内容。
"""
    
    async def parse_task_command(self, user_message: str, current_tasks: List[Task]) -> TaskCommand:
        """解析任务命令"""
        try:
            # 格式化任务列表用于显示
            task_list = self._format_task_list_for_ai(current_tasks)
            
            prompt = self.command_parsing_prompt.format(
                task_list=task_list,
                user_message=user_message
            )
            
            result = await get_ai_service().generate_text(
                prompt,
                temperature=0.2,
                max_tokens=500
            )
            
            if not result.success:
                logger.error(f"Command parsing failed: {result.error}")
                return TaskCommand(type=TaskCommandType.UNKNOWN, raw_message=user_message)
            
            try:
                command_data = json.loads(result.result.strip())
                return self._parse_command_data(command_data, user_message)
            except json.JSONDecodeError as e:
                logger.error(f"Failed to parse command JSON: {e}")
                return TaskCommand(type=TaskCommandType.UNKNOWN, raw_message=user_message)
                
        except Exception as e:
            logger.error(f"Task command parsing error: {e}")
            return TaskCommand(type=TaskCommandType.UNKNOWN, raw_message=user_message)
    
    def _parse_command_data(self, data: Dict[str, Any], raw_message: str) -> TaskCommand:
        """解析命令数据"""
        try:
            command_type = TaskCommandType(data.get('type', 'unknown'))
        except ValueError:
            command_type = TaskCommandType.UNKNOWN
        
        return TaskCommand(
            type=command_type,
            target_task_index=data.get('target_task_index'),
            new_description=data.get('new_description'),
            new_position=data.get('new_position'),
            parameters=data.get('parameters', {}),
            raw_message=raw_message
        )
    
    async def execute_task_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行任务命令"""
        try:
            if command.type == TaskCommandType.ADD:
                return await self._execute_add_command(command, current_tasks)
            elif command.type == TaskCommandType.MODIFY:
                return await self._execute_modify_command(command, current_tasks)
            elif command.type == TaskCommandType.DELETE:
                return await self._execute_delete_command(command, current_tasks)
            elif command.type == TaskCommandType.REORDER:
                return await self._execute_reorder_command(command, current_tasks)
            elif command.type == TaskCommandType.CONFIRM:
                return self._execute_confirm_command(command, current_tasks)
            else:
                return TaskCommandResult(
                    success=False,
                    message="抱歉，我无法理解您的请求。请尝试更明确的描述，比如'修改第2个任务'或'添加一个新任务'。",
                    error="Unknown command type"
                )
                
        except Exception as e:
            logger.error(f"Task command execution error: {e}")
            return TaskCommandResult(
                success=False,
                message="执行命令时发生错误，请重试。",
                error=str(e)
            )
    
    async def _execute_add_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行添加任务命令"""
        if not command.new_description:
            return TaskCommandResult(
                success=False,
                message="请提供新任务的描述。",
                error="Missing task description"
            )
        
        # 创建新任务
        new_task = Task(
            description=command.new_description,
            type=TaskType.RESEARCH,  # 默认类型
            required_capabilities=[AICapability.TEXT_GENERATION],
            estimated_duration=60,
            priority=len(current_tasks) + 1
        )
        
        # 插入到指定位置或末尾
        updated_tasks = current_tasks.copy()
        if command.new_position and 1 <= command.new_position <= len(updated_tasks) + 1:
            updated_tasks.insert(command.new_position - 1, new_task)
        else:
            updated_tasks.append(new_task)
        
        return TaskCommandResult(
            success=True,
            message=f"已添加新任务：{command.new_description}",
            updated_tasks=updated_tasks
        )
    
    async def _execute_modify_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行修改任务命令"""
        if not command.target_task_index or command.target_task_index < 1 or command.target_task_index > len(current_tasks):
            return TaskCommandResult(
                success=False,
                message="请指定要修改的任务编号（1到{}）。".format(len(current_tasks)),
                error="Invalid task index"
            )
        
        if not command.new_description:
            return TaskCommandResult(
                success=False,
                message="请提供新的任务描述。",
                error="Missing new description"
            )
        
        updated_tasks = current_tasks.copy()
        task_index = command.target_task_index - 1
        old_description = updated_tasks[task_index].description
        updated_tasks[task_index].description = command.new_description
        
        return TaskCommandResult(
            success=True,
            message=f"已将第{command.target_task_index}个任务从'{old_description[:30]}...'修改为'{command.new_description}'",
            updated_tasks=updated_tasks
        )
    
    async def _execute_delete_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行删除任务命令"""
        if not command.target_task_index or command.target_task_index < 1 or command.target_task_index > len(current_tasks):
            return TaskCommandResult(
                success=False,
                message="请指定要删除的任务编号（1到{}）。".format(len(current_tasks)),
                error="Invalid task index"
            )
        
        updated_tasks = current_tasks.copy()
        task_index = command.target_task_index - 1
        deleted_task = updated_tasks.pop(task_index)
        
        # 移除对删除任务的依赖
        deleted_task_id = deleted_task.id
        for task in updated_tasks:
            if deleted_task_id in task.dependencies:
                task.dependencies.remove(deleted_task_id)
        
        return TaskCommandResult(
            success=True,
            message=f"已删除第{command.target_task_index}个任务：{deleted_task.description[:30]}...",
            updated_tasks=updated_tasks
        )
    
    async def _execute_reorder_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行重排序任务命令"""
        if not command.target_task_index or not command.new_position:
            return TaskCommandResult(
                success=False,
                message="请指定要移动的任务编号和新位置。",
                error="Missing task index or new position"
            )
        
        if (command.target_task_index < 1 or command.target_task_index > len(current_tasks) or
            command.new_position < 1 or command.new_position > len(current_tasks)):
            return TaskCommandResult(
                success=False,
                message=f"任务编号和位置应该在1到{len(current_tasks)}之间。",
                error="Invalid task index or position"
            )
        
        updated_tasks = current_tasks.copy()
        task_index = command.target_task_index - 1
        new_index = command.new_position - 1
        
        # 移动任务
        task = updated_tasks.pop(task_index)
        updated_tasks.insert(new_index, task)
        
        return TaskCommandResult(
            success=True,
            message=f"已将第{command.target_task_index}个任务移动到第{command.new_position}位。",
            updated_tasks=updated_tasks
        )
    
    def _execute_confirm_command(self, command: TaskCommand, current_tasks: List[Task]) -> TaskCommandResult:
        """执行确认命令"""
        validation = self.validate_task_sequence(current_tasks)
        
        if not validation.is_valid:
            return TaskCommandResult(
                success=False,
                message=f"任务序列验证失败：{'; '.join(validation.errors)}",
                error="Task validation failed"
            )
        
        return TaskCommandResult(
            success=True,
            message="任务序列验证通过，可以开始执行。",
            updated_tasks=current_tasks
        )
    
    def validate_task_sequence(self, tasks: List[Task]) -> ValidationResult:
        """验证任务序列"""
        result = ValidationResult(is_valid=True)
        
        if not tasks:
            result.add_error("任务列表为空")
            return result
        
        task_ids = {task.id for task in tasks}
        
        for i, task in enumerate(tasks):
            if not task.description.strip():
                result.add_error(f"第{i+1}个任务缺少描述")
            
            # 检查依赖关系
            for dep_id in task.dependencies:
                if dep_id not in task_ids:
                    result.add_error(f"第{i+1}个任务依赖的任务不存在")
        
        return result
    
    def _format_task_list_for_ai(self, tasks: List[Task]) -> str:
        """格式化任务列表用于AI分析"""
        if not tasks:
            return "当前没有任务。"
        
        formatted_tasks = []
        for i, task in enumerate(tasks, 1):
            formatted_tasks.append(f"{i}. {task.description}")
        
        return "\n".join(formatted_tasks)


# 全局实例
task_manager = TaskManager()